/**   
* @{#} Compute.java Create on 2013-6-22 下午7:41:48   
*   
* Copyright (c) 2012 by Baidu.   
*/
package objtable.algm;

import java.util.HashMap;
import java.util.List;

import objtable.core.ScriptEnv;
import objtable.core.TableCenter;
import objtable.struct.Row;

/**   
* @author <a href="mailto:zhangbo07@baidu.com">zhangbo07</a>  
* @version 1.0   
* 计算算子，主要用来将表达式应用到输入的Row对象上，自定义函数也可以直接应用到这里
* 比如：
* 		ComputeBy c = new ComputeBy("price1=10/age;price2=sum(price,price1)");
		List<? extends Row> l = c.getResult(rows);
* 
*/

public class ComputeBy implements Algm1Row {
	private String express;

	/**
	 * 构造计算用算子
	 * @param complexExpress 复杂表达式（指令集，指令之间通过;号分隔）
	 */
	public ComputeBy(String complexExpress) {
		this.express = complexExpress;
	}

	public List<? extends Row> execute(List<? extends Row> rows) {
		if (rows.size() > 0) {
			String[] fields = TableCenter.getTable(rows.get(0).getTableName())
					.getFields();
			String exp = wrapExpressWithFor(fields, "obj.");
			HashMap<String, Object> cmp = ScriptEnv.cloneComputeObj();
			cmp.put("objs", rows);

			ScriptEnv.execute(exp, cmp);
		}
		return rows;
	}

	/**
	 * 
	 * @param fields	Row包含的所有字段
	 * @param prefix	每个字段前面需要添加的前缀
	 * 比如：price*2转化成for(obj:objs){obj.price*2;},外面再套上一层for循环即可
	 * @return 套上for循环，添加完字段前缀后的表达式
	 */
	private String wrapExpressWithFor(String[] fields, String prefix) {
		String result = ScriptEnv.replaceFieldsWithPrefix(express, fields,
				prefix);
		result = "size=objs.size();for(i=0;i<size;i++){obj=objs.get(i);"
				+ result + "}";
		return result;
	}
}
